home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 41.zip / BS1 part 41 / parallel-C disk .adf / afserver.c < prev    next >
C/C++ Source or Header  |  1997-12-31  |  31KB  |  1,350 lines

  1. /**************************************************************************
  2. *
  3. *  Alien File Server
  4. *
  5. *  12th March 1987.
  6. *
  7. *  Copyright INMOS Limited, 1987.
  8. *
  9. *  Upgrade to 3L-Server by Gerhard Bartz
  10. *
  11. *  18th April 1989
  12. *
  13. ***************************************************************************/
  14.  
  15. #define LINT_ARGS 1      /* Enable Compiler Parameter Checking */
  16. #include <stdio.h>
  17. #include <stat.h>
  18. #include <time.h>
  19. #include <string.h>
  20.  
  21. #include "srvconst.h"
  22.  
  23. extern char *mktemp();   
  24.  
  25. extern unsigned int link_base;
  26. /* Server static variables */
  27. /* Transputer command line buffer. Contains parameters from the server */
  28. /* command line which the server does not recognise. */
  29. static char tcom[COMMAND_LINE_LENGTH];
  30. static int tcominptr = 0, tcomoutptr = 0;
  31. static int terminate_code;                    /* Server result */
  32. static int transputer_result = 0;             /* Result from transputer */
  33. static int command;
  34. static int boot_file_exists = FALSE;          /* If true, use boot file */
  35. static int alien_option_flag = 0x0;
  36. static char version[] =
  37.    "Alien file server V1.3 (14th October 1987) + 3L 15th January 1988\n";
  38. static char copyright[] =
  39.    "Copyright INMOS Ltd, 1985\n";
  40.  
  41. static struct STREAM_DESC filers[N_STREAMS];
  42.  
  43. static char *open_types [MAX_OPEN_MODE+1]
  44.   [MAX_EXIST_MODE+1][MAX_ACCESS_METHOD+1] =
  45.     { { { "r",  "r"  }, { "r",  "r" } },
  46.       { { "r+", "r+" }, { "w",  "w" } },
  47.       { { "r+", "r+" }, { "w+", "w+"} } };
  48. /* Server global variables */
  49. int running;                   /* Server is running flag */
  50. int test_error_flag = FALSE;   /* If true, test error flag */
  51.  
  52. /* Routine to convert MSDOS backslashes to AMIGA slashes*/
  53.  
  54. char *slashconv(name)
  55. char *name;
  56. {
  57.    char *hp;
  58. #ifdef DEBUG
  59.    printf("Converting %s !\n",name);
  60. #endif
  61.    hp=index(name,'\\');
  62.    if (hp!=NULL) *hp=':';
  63.    for (hp=index(name,'\\');hp!=NULL;hp=index(hp,'\\')) *hp='/';
  64. #ifdef DEBUG
  65.    printf("Opening file %s !\n",name);
  66. #endif
  67.    return(name);
  68. }
  69.  
  70. void terminate_server (t_code)
  71. int t_code;
  72. /* Set flags to terminate the server. */
  73. {
  74.     terminate_code = t_code;
  75.     running = FALSE;
  76. }
  77.  
  78. int fexists (file_str)
  79. char *file_str;
  80. /* Return TRUE if the file whose name is in file_str exists,
  81.    FALSE otherwise. */
  82. {
  83.     FILE *stream;
  84.     if ( (stream = fopen (slashconv(file_str), "r")) != NULL )
  85.     {
  86.         fclose (stream);
  87.         return (TRUE);
  88.     } else
  89.         return (FALSE);
  90. }
  91.  
  92. int filer_close_file (streamp, close_mode)
  93. struct STREAM_DESC *streamp;
  94. int close_mode;
  95. {
  96.     int res = F_OK;
  97.     if ( (close_mode >= 0) && (close_mode <= MAX_CLOSE_OPTION) )
  98.     {
  99.         if (streamp->lifetime_m != SPECIAL)
  100.         {
  101.             if (fclose (streamp->fileptr) == 0)
  102.             {
  103. if ((close_mode == CLOSEDEL_OPTION) ||
  104.     (streamp->lifetime_m == TEMPORARY))
  105. {
  106.     if (unlink (streamp->name) != 0)
  107.     {
  108.         res = OPERATIONFAILED_ERR;
  109.     };
  110. };
  111.                 streamp->inuse = FALSE;
  112.             } else
  113.             {
  114.                 res = OPERATIONFAILED_ERR;
  115.                 /* Remove our reference anyway */
  116.                 streamp->inuse = FALSE;
  117.             };
  118.         } else
  119.             streamp->inuse = FALSE; /* Just remove our reference */
  120.     } else
  121.         res = INVALIDCLOSEOPTION_ERR;
  122.     return (res);
  123. }
  124.  
  125. void filer_close ()
  126. {
  127.     int i;
  128.     for (i = 0; i < N_STREAMS; i++)
  129.         if ( filers[i].inuse )
  130.         {
  131.             filer_close_file ( &(filers[i]), CLOSE_OPTION );
  132.             filers[i].inuse = FALSE;
  133.         };
  134. }
  135.  
  136. void record_to_string (rec, len, str)
  137. char *rec;
  138. int len;
  139. char *str;
  140. {
  141.   int i;
  142.   for (i = 0; i < len; i++)
  143.     *str++ = rec[i];
  144.   *str = '\0';
  145. }
  146.  
  147. void string_to_record (str, rec, len)
  148. char *str;
  149. char *rec;
  150. int  *len;
  151. {
  152.     int i = 0;
  153.     while (*str != '\0')
  154.         rec[i++] = *str++;
  155.     *len = i;
  156. }
  157.  
  158. int find_stream ()
  159. {
  160.     int i = 0;
  161.     int found = FALSE;
  162.     while( (i < N_STREAMS) && (found == FALSE) )
  163.     {
  164.         if ((filers[i].inuse) == FALSE)
  165.             found = TRUE;
  166.         else
  167.             i++;
  168.     };
  169.     if (found)
  170.         return (i);
  171.     else
  172.         return (INVALID_STREAM);
  173. }
  174.  
  175.  
  176. int valid_stream (n)
  177. int n;
  178. {
  179.     if ( (n >= 0) && (n < N_STREAMS) )
  180.         if (filers[n].inuse)
  181.             return (TRUE);
  182.     return (FALSE);
  183. }
  184.  
  185. int make_file_name (n)
  186. char *n;
  187. {
  188.     char *template = "afXXXXXX";
  189.     char *result;
  190.     result = mktemp(template);
  191.     strcpy (n, result);
  192.     if (*n=='\0') return(FALSE);
  193.     return (TRUE);
  194. }
  195.  
  196. int make_af_err (c_err)
  197. int c_err;
  198. {
  199.     return (HOST_ERROR_BASE - c_err);
  200. }
  201.  
  202. int seek_file_length (fptr, length)
  203. FILE *fptr;
  204. long *length;
  205. {
  206.     long curpos;
  207.     int result = F_OK;
  208.     curpos = ftell(fptr);                    /* Remember where we are    */
  209.     if (fseek(fptr, 0L, 2) == 0)             /* Go to the end to find    */
  210.         *length = ftell(fptr);               /* where it is              */
  211.     else
  212.         result = OPERATIONFAILED_ERR;
  213.     if (fseek(fptr, curpos, 0) != 0)            /* Go back to where */
  214.         result = OPERATIONFAILED_ERR;          /* We were          */
  215.     return (result);
  216. }
  217.  
  218. int tag_from_link ()
  219. {
  220.     return (word_from_link());
  221. }
  222.  
  223. int read_integer (v)
  224. int *v;
  225. {
  226.     if (tag_from_link() == INT32_VALUE)
  227.     {
  228.         *v = word_from_link ();
  229.         return (TRUE);
  230.     } else
  231.     {
  232.         fprintf (stderr,"Last command = %n\n", command);
  233.         terminate_server (T_BAD_INT32);
  234.         return (FALSE);
  235.     };
  236. }
  237.  
  238. extern long int long_word_from_link();
  239. int read_long_integer (v)
  240. long int *v;
  241. {
  242.     if (tag_from_link() == INT32_VALUE)
  243.     {
  244.         *v = long_word_from_link ();
  245.         return (TRUE);
  246.     } else
  247.     {
  248.         fprintf (stderr,"Last command = %n\n", command);
  249.         terminate_server (T_BAD_INT32);
  250.         return(FALSE);
  251.     };
  252. }
  253.  
  254. int read_record (len, buffer)
  255. int *len;
  256. char *buffer;
  257. {
  258.     int t = tag_from_link ();
  259.     if (t == NILRECORD_VALUE)
  260.     {
  261.         *len = 0;
  262.         return (TRUE);
  263.     } else
  264.         if (t == RECORD32_VALUE)
  265.         {
  266.             *len = trunc_slice_from_link (RECORD_LENGTH, buffer);
  267.             return (TRUE);
  268.         } else
  269.         {
  270.             fprintf (stderr, "Last command = %n\n", command);
  271.             terminate_server (T_BAD_RECORD);
  272.             return (FALSE);
  273.         };
  274. }
  275.  
  276. int read_long_record (len, buffer)
  277. long int *len;
  278. char *buffer;
  279. {
  280.     int t = tag_from_link ();
  281.     if (t == NILRECORD_VALUE)
  282.     {
  283.         *len = 0;
  284.         return (TRUE);
  285.     } else
  286.         if (t == RECORD32_VALUE)
  287.         {
  288.             long_slice_from_link (len, buffer);
  289.             return (TRUE);
  290.         } else
  291.         {
  292.             fprintf (stderr, "Last command = %n\n", command);
  293.             terminate_server (T_BAD_RECORD);
  294.             return (FALSE);
  295.         };
  296. }
  297.  
  298. void tag_to_link (tag)
  299. int tag;
  300. {
  301.     word_to_link (tag);
  302. }
  303.  
  304. void write_integer (n)
  305. int n;
  306. {
  307.     tag_to_link (INT32_VALUE);
  308.     word_to_link (n);
  309. }
  310.  
  311. void write_long_integer (n)
  312. long int n;
  313. {
  314.     tag_to_link (INT32_VALUE);
  315.     long_word_to_link (n);
  316. }
  317.  
  318. void write_record (len, buffer)
  319. int len;
  320. char *buffer;
  321. {
  322.     if (len == 0)
  323.         tag_to_link (NILRECORD_VALUE);
  324.     else
  325.     {
  326.         tag_to_link (RECORD32_VALUE);
  327.         slice_to_link (len, buffer);
  328.     };
  329. }
  330.  
  331. void write_long_record (len, buffer)
  332. long int len;
  333. char *buffer;
  334. {
  335.     if (len == 0)
  336.         tag_to_link (NILRECORD_VALUE);
  337.     else
  338.     {
  339.         tag_to_link (RECORD32_VALUE);
  340.         long_slice_to_link (len, buffer);
  341.     };
  342. }
  343.  
  344. void open_temp ()
  345. {
  346.     int access_method, record_length;
  347.     int stream_id = INVALID_STREAM;
  348.     int res = F_OK;
  349.     if (read_integer (&access_method))
  350.     if (read_integer (&record_length))
  351. {
  352. if ((access_method >= 0) && (access_method <= MAX_ACCESS_METHOD))
  353. {
  354. stream_id = find_stream ();
  355. if (stream_id >= 0)
  356. {
  357.     struct STREAM_DESC *streamp = &filers[stream_id];
  358.     if (make_file_name (streamp->name))
  359.     {
  360. char *type = open_types[UPDATE_MODE][NEW_FILE][access_method];
  361. FILE *fptr;
  362. fptr = fopen (slashconv(streamp->name), type);
  363. if (fptr != NULL)
  364. {
  365.     streamp->inuse = TRUE;
  366.     streamp->fileptr = fptr;
  367.     streamp->open_m = UPDATE_MODE;
  368.     streamp->exist_m = NEW_FILE;
  369.     streamp->access_m = access_method;
  370.     streamp->lifetime_m = TEMPORARY;
  371.     streamp->result = F_OK;
  372. } else
  373.     res = OPERATIONFAILED_ERR;
  374.     } else
  375.         res = OPERATIONFAILED_ERR;
  376. } else
  377.     res = NOFREECHANNEL_ERR;
  378. } else
  379.     res = INVALIDACCESSMETHOD_ERR;
  380. write_integer (stream_id);
  381. write_integer (res);
  382. };
  383. }
  384.  
  385. void open_file (lifetime)
  386. int lifetime;
  387. {
  388.     char filename [FILE_NAME_LENGTH];
  389.     int len = 0;
  390.     int access_method, open_mode, exist_mode, record_length;
  391.     int res = F_OK;
  392.     if (read_record (&len, filename))
  393.     if (read_integer (&access_method))
  394.     if (read_integer (&open_mode))
  395.     if (read_integer (&exist_mode))
  396.     if (read_integer (&record_length))
  397. {
  398.     int stream = INVALID_STREAM;
  399.     if ((access_method >= 0) && (access_method <= MAX_ACCESS_METHOD))
  400.     {
  401.         if ((open_mode >= 0) && (open_mode <= MAX_OPEN_MODE))
  402.         {
  403.             if ((exist_mode >= 0) && (exist_mode <= MAX_EXIST_MODE))
  404.             {
  405. stream = find_stream ();
  406. if (stream >= 0)
  407. {
  408.     struct STREAM_DESC *streamp = &filers[stream];
  409.     record_to_string (filename, len, streamp->name);
  410.     {
  411. char *type = open_types[open_mode][exist_mode][access_method];
  412. FILE *fptr;
  413. fptr = fopen (slashconv(streamp->name), type);
  414. if (fptr != NULL)
  415. {
  416.     streamp->inuse = TRUE;
  417.     streamp->fileptr = fptr;
  418.     streamp->open_m = open_mode;
  419.     streamp->exist_m = exist_mode;
  420.     streamp->access_m = access_method;
  421.     streamp->lifetime_m = lifetime;
  422.     streamp->result = F_OK;
  423. } else
  424.     res = OPERATIONFAILED_ERR;
  425.     };
  426. } else
  427.     res = NOFREECHANNEL_ERR;
  428.             } else
  429.                 res = INVALIDEXISTMODE_ERR;
  430.         } else
  431.             res = INVALIDOPENMODE_ERR;
  432.     } else
  433.         res = INVALIDACCESSMETHOD_ERR;
  434.     write_integer (stream);
  435.     write_integer (res);
  436. };
  437. }
  438.  
  439. void open_stream (open_mode)
  440. int open_mode;
  441. {
  442.     int stream_id = INVALID_STREAM;
  443.     int std_stream_no;
  444.     int res = F_OK;
  445.     if (read_integer(&std_stream_no))
  446.     {
  447.         if (open_mode == S_INPUT)
  448.         { 
  449. switch (std_stream_no)
  450. {
  451. case 0:
  452.     stream_id = find_stream ();
  453.     if (stream_id >= 0)
  454.     {
  455. struct STREAM_DESC *streamp = &filers[stream_id];
  456. streamp->inuse = TRUE;
  457. strcpy (streamp->name, "stdin");
  458. streamp->fileptr = stdin;
  459. streamp->open_m = READ_MODE;
  460. streamp->exist_m = OLD_FILE;
  461. streamp->access_m = TEXTBYTESTREAM_ACCESS;
  462. streamp->lifetime_m = SPECIAL;
  463. streamp->result = F_OK;
  464.     } else
  465.         res = NOFREECHANNEL_ERR;
  466.     break;
  467. case 1:
  468.     stream_id = PARAM_STREAM;
  469.     break;
  470. default:
  471.     res = INVALIDSTDSTREAM_ERR;
  472. };
  473.         } else
  474.             if (open_mode == S_OUTPUT)
  475.             {
  476. switch (std_stream_no)
  477. {
  478. case 0:
  479.     stream_id = find_stream ();
  480.     if (stream_id >= 0)
  481.     {
  482. struct STREAM_DESC *streamp = &filers[stream_id];
  483. streamp->inuse = TRUE;
  484. strcpy (streamp->name, "stdout");
  485. streamp->fileptr = stdout;
  486. streamp->open_m = WRITE_MODE;
  487. streamp->exist_m = OLD_FILE;
  488. streamp->access_m = TEXTBYTESTREAM_ACCESS;
  489. streamp->lifetime_m = SPECIAL;
  490. streamp->result = F_OK;
  491.     } else
  492.         res = NOFREECHANNEL_ERR;
  493.     break;
  494. case 1:
  495.     stream_id = find_stream ();
  496.     if (stream_id >= 0)
  497.     {
  498. struct STREAM_DESC *streamp = &filers[stream_id];
  499. streamp->inuse = TRUE;
  500. strcpy (streamp->name, "stderr");
  501. streamp->fileptr = stderr;
  502. streamp->open_m = WRITE_MODE;
  503. streamp->exist_m = OLD_FILE;
  504. streamp->access_m = TEXTBYTESTREAM_ACCESS;
  505. streamp->lifetime_m = SPECIAL;
  506. streamp->result = F_OK;
  507.     } else
  508.         res = NOFREECHANNEL_ERR;
  509.     break;
  510. default:
  511.     res = INVALIDSTDSTREAM_ERR;
  512. };
  513.             };
  514.         write_integer (stream_id);
  515.         write_integer (res);
  516.     };
  517. }
  518.  
  519. void close_stream ()
  520. {
  521.     int stream_id = INVALID_STREAM;
  522.     int close_mode;
  523.     int res = F_OK;
  524.     if (read_integer(&stream_id))
  525.     if (read_integer(&close_mode))
  526.     {
  527.         if (valid_stream (stream_id))
  528.         {
  529.             res = filer_close_file (&(filers[stream_id]), close_mode);
  530.         } else
  531.         {
  532.             if (stream_id == PARAM_STREAM)
  533.                 tcomoutptr = 0;
  534.             else
  535.                 res = INVALIDSTREAMID_ERR;
  536.         };
  537.         write_integer (res);
  538.     };
  539. }
  540.  
  541. void read_block ()
  542. {
  543.     int stream_id = INVALID_STREAM;
  544.     int record_len = 0;
  545.     int res = F_OK;
  546.     int bytes_read = 0;
  547.     char buffer[RECORD_LENGTH];
  548.     if (read_integer (&stream_id))
  549.     if (read_integer (&record_len))
  550.     { 
  551.         if (valid_stream (stream_id))
  552. {
  553.     struct STREAM_DESC *streamp = &filers[stream_id];
  554.     if ((record_len >= 0) && (record_len <= RECORD_LENGTH))
  555.     {
  556.         if (streamp->fileptr == stdin)
  557.         {
  558.             int chr = '\0';
  559.             while ((chr != EOF) && (bytes_read < record_len))
  560.             {
  561.                 chr = getchar();
  562.                 buffer[bytes_read++] = chr;
  563.                 if (chr == EOF)
  564.                     bytes_read--;            /* Remove EOF from block */
  565.                 else if (chr == '\n')
  566.                     break;
  567.             }
  568.         } else
  569.             bytes_read = fread(buffer, 1, record_len, streamp->fileptr);
  570.         if (feof(streamp->fileptr))
  571.         {
  572.             streamp->result = F_EOF; res = F_EOF;
  573.         } else
  574.         {
  575.             int r = ferror(streamp->fileptr);
  576.             streamp->result = make_af_err(r);
  577.             if (r != 0)
  578.                 res = OPERATIONFAILED_ERR;
  579.         };
  580.     } else
  581.         res = INVALIDRECORDLENGTH_ERR;
  582.         } else
  583.         {
  584.             if (stream_id == PARAM_STREAM)
  585. {
  586.     if ((record_len >=0) && (record_len <= RECORD_LENGTH))
  587.     {
  588.         bytes_read = tcomread(buffer, record_len);
  589.         if (bytes_read < record_len)
  590.             res = F_EOF;
  591.     } else
  592.         res = INVALIDRECORDLENGTH_ERR;
  593.         } else
  594.             {
  595.                 res = INVALIDSTREAMID_ERR;
  596.             };
  597.         };
  598.         write_record (bytes_read, buffer);
  599.         write_integer (res);
  600.     };
  601. }
  602.  
  603. void write_block ()
  604. {
  605.     int stream_id = INVALID_STREAM;
  606.     int record_len = 0;
  607.     int bytes_written = 0;
  608.     char buffer [RECORD_LENGTH];
  609.     int res = F_OK;
  610.     if (read_integer (&stream_id))
  611.     if (read_record (&record_len, buffer))
  612.     {
  613.         if (valid_stream (stream_id))
  614. {
  615.     struct STREAM_DESC *streamp = &filers[stream_id];
  616.     bytes_written = fwrite (buffer, 1, record_len, streamp->fileptr);
  617.     if (bytes_written != record_len)
  618.     {
  619.         streamp->result = make_af_err(ferror(streamp->fileptr));
  620.         res = OPERATIONFAILED_ERR;
  621.     };
  622.         } else
  623.             res = INVALIDSTREAMID_ERR;
  624.         write_integer (bytes_written);
  625.         write_integer (res);
  626.     };
  627. }
  628.  
  629. void stream_seek ()
  630. {
  631.     int stream_id = INVALID_STREAM;
  632.     long int offset = 0;
  633.     int res = F_OK;
  634.     if (read_integer (&stream_id))
  635.     if (read_long_integer (&offset))
  636.     {
  637.         if (valid_stream (stream_id))
  638.         {
  639.             struct STREAM_DESC *streamp = &filers[stream_id];
  640.             int r;
  641.             if ((r = fseek(streamp->fileptr, offset, 0)) != 0)
  642.             {
  643.                 streamp->result = make_af_err(r);
  644.                 res = OPERATIONFAILED_ERR;
  645.             } else
  646.                 streamp->result = F_OK;
  647.         } else
  648.         {
  649.             if (stream_id == PARAM_STREAM)
  650.                 res = NOSEEKPOSSIBLE_ERR;
  651.             else
  652.                 res = INVALIDSTREAMID_ERR;
  653.         };
  654.         write_integer (res);
  655.     };
  656. }
  657.  
  658. void stream_file ()
  659. {
  660.     int stream_id;
  661.     if (read_integer (&stream_id))
  662.     {
  663.         char filename[RECORD_LENGTH];
  664.         int len = 0;
  665.         int res = F_OK;
  666.         if (valid_stream(stream_id))
  667.         {
  668.             struct STREAM_DESC *streamp = &filers[stream_id];
  669.             string_to_record (streamp->name, filename, &len);
  670.         } else
  671.         {
  672.             if (stream_id == PARAM_STREAM)
  673.                 string_to_record ("Command line", filename, &len);
  674.             else
  675.                 res = INVALIDSTREAMID_ERR;
  676.         };
  677.         write_record (len, filename);
  678.         write_integer (res);
  679.     };
  680. }
  681.  
  682. void stream_connect ()
  683. {
  684.     int stream_id;
  685.     if (read_integer (&stream_id))
  686.     {
  687.         int device_connected = -1;
  688.         int res = F_OK;
  689.         if (valid_stream(stream_id))
  690. {
  691.     struct STREAM_DESC *streamp = &filers[stream_id];
  692.     struct stat buffer;
  693.     if (stat(streamp->name, &buffer) == 0)
  694.     {
  695. if (isatty(fileno(streamp->fileptr)))
  696. {   /* We are connected to a device */
  697.     if (strcmp ("stdin", streamp->name) == 0)
  698.         device_connected = KEYBOARD_USE;
  699.     else
  700.     {
  701.         if ((strcmp ("stdout", streamp->name) == 0) ||
  702.             (strcmp ("stderr", streamp->name) == 0))
  703.             device_connected = SCREEN_USE;
  704.         else
  705.             res = OPERATIONFAILED_ERR;
  706.     };
  707. } else
  708. {
  709.     if (buffer.st_attr & ST_DELETE)
  710.     { /* We are connected to a file */
  711.         if (streamp->lifetime_m == TEMPORARY)
  712.             device_connected = TEMP_USE;
  713.         else
  714.             device_connected = FILE_USE;
  715.     } else
  716.         res = OPERATIONFAILED_ERR;
  717. };
  718.     } else
  719.         res = OPERATIONFAILED_ERR;
  720.         } else
  721.         {
  722.             if (stream_id == PARAM_STREAM)
  723.                 device_connected = PARAMETER_USE;
  724.             else
  725.                 res = INVALIDSTREAMID_ERR;
  726.         };
  727.         write_integer (device_connected);
  728.         write_integer (res);
  729.      };
  730. }
  731.  
  732. void stream_access ()
  733. {
  734.     int stream_id;
  735.     if (read_integer (&stream_id))
  736.     {
  737.         int access_method = 0;
  738.         int res = F_OK;
  739.         if (valid_stream(stream_id))
  740.         {
  741.             struct STREAM_DESC *streamp = &filers[stream_id];
  742.             access_method = streamp->access_m;
  743.         } else
  744.         {
  745.             if (stream_id == PARAM_STREAM)
  746.                 access_method = TEXTBYTESTREAM_ACCESS;
  747.             else
  748.             res = INVALIDSTREAMID_ERR;
  749.         };
  750.         write_integer (access_method);
  751.         write_integer (res);
  752.      };
  753. }
  754.  
  755. void stream_length ()
  756. {
  757.     int stream_id;
  758.     if (read_integer (&stream_id))
  759.     {
  760.         int res = F_OK;
  761.         long int len = 0L;
  762.         if (valid_stream(stream_id))
  763.         {
  764.             struct STREAM_DESC *streamp = &filers[stream_id];
  765.             res = seek_file_length(streamp->fileptr, &len);
  766.         } else
  767.         {
  768.             if (stream_id == PARAM_STREAM)
  769.                 len = (long) tcominptr;
  770.             else
  771.                 res = INVALIDSTREAMID_ERR;
  772.         };
  773.         write_long_integer (len);
  774.         write_integer (res);
  775.      };
  776. }
  777.  
  778. void stream_status ()
  779. {
  780.     int stream_id;
  781.     if (read_integer (&stream_id))
  782.     {
  783.         int res = F_OK;
  784.         if (valid_stream(stream_id))
  785.         {
  786.             struct STREAM_DESC *streamp = &filers[stream_id];
  787.             res = streamp->result;
  788.         } else
  789.         {
  790.             if (stream_id == PARAM_STREAM)
  791.             {
  792.                 if (tcominptr == tcomoutptr)
  793.                     res = F_EOF;
  794.                 else
  795.                     res = F_OK;
  796.             } else
  797.                 res = INVALIDSTREAMID_ERR;
  798.         };
  799.         write_integer (res);
  800.      };
  801. }
  802.  
  803. void set_result ()
  804. {
  805.     if (read_integer(&transputer_result))
  806.     {
  807.         write_integer (F_OK);
  808.     }
  809. }
  810.  
  811. void run_command ()
  812. {
  813.     int record_len = 0, res = F_OK;
  814.     char buffer [RECORD_LENGTH + 1];
  815.     if (read_record (&record_len, buffer))
  816.     {
  817.         buffer [record_len] = '\0';
  818.         res = 1;                                  /* If ok, returns 0 */
  819.         if (res != 0)                             /* Not ok, returns -1 */
  820.             write_integer (OPERATIONFAILED_ERR);
  821.         else
  822.             write_integer (F_OK);
  823.     };
  824. }
  825.  
  826. void rename_file ()
  827. {
  828.     int old_len = 0;
  829.     int new_len = 0;
  830.     char old_name [RECORD_LENGTH], new_name [RECORD_LENGTH];
  831.     int res = F_OK;
  832.     if (read_record (&old_len, old_name))
  833.     if (read_record (&new_len, new_name))
  834.     {
  835.         res = rename (new_name, old_name);       /* If ok, returns 0 */
  836.         if (res != 0)                          /* Not ok, returns non-zero */
  837.             write_integer (OPERATIONFAILED_ERR);
  838.         else
  839.             write_integer (F_OK);
  840.     };
  841. }
  842.  
  843. void read_time ()
  844. {
  845.     /* beinhaltet Umrechnung eines bitkodierten Datums (Amiga)  */
  846.     /* auf die Sekunden seit dem 1.1.1970, 0.00 h               */
  847.     long int seconds,dummy;
  848.     (void) time(&dummy);
  849.     seconds =((dummy<<1 )&31L) + (60L*((dummy<<6 )&31L));
  850.     seconds+=(3600L*((dummy<<11)&31L))+(24L*3600L*((dummy<<16)&31L));
  851.     seconds+= (30L*24L*3600L*((dummy<<21)&15L));
  852.     seconds+=(365L*24L*3600L*((dummy<<25)&31L));
  853.     seconds+=(10L*365L*24L*3600L) - (30L*24L*3600L);
  854.     write_long_integer (seconds);
  855.     write_integer (F_OK);
  856. }
  857.  
  858. void read_key ()
  859. {
  860.     int key = 0, key_hit=0;        /*1*/
  861.                      /* character in keyboard buffer ? */
  862.     if (key_hit != 0)                /* returns non-zero if key pressed */
  863.         key = (int)getchar();        /* get key and echo it */
  864.     write_integer (key);
  865.     if (key_hit != 0) 
  866.         write_integer (F_OK);
  867.     else 
  868.     write_integer (OPERATIONFAILED_ERR);
  869. }
  870.  
  871.  
  872. /**** ADD1 begin ****/
  873.  
  874. void run_time_data()
  875. {
  876.    int option;
  877.  
  878.    if (read_integer(&option))
  879.    {
  880.       switch (option)
  881.       {
  882.          case 0:
  883.             write_integer(alien_option_flag);
  884.             write_integer(F_OK);
  885.             break;
  886.          default:
  887.             write_integer(0);
  888.             write_integer(OPERATIONFAILED_ERR);
  889.             break;
  890.       }
  891.    }
  892. }
  893.  
  894.  
  895. void read_environment()
  896. {
  897.    int block_size;
  898.    char buffer[RECORD_LENGTH+1];
  899.  
  900.    if (read_record(&block_size,buffer))
  901.    {
  902.       char *ptr;
  903.      extern char *getenv();
  904.  
  905.      buffer[block_size] = '\0';
  906.      ptr = getenv(buffer);
  907.      if (ptr==NULL)
  908.      {
  909.          write_record(0,"");
  910.          write_integer(OPERATIONFAILED_ERR);
  911.      }
  912.      else
  913.      {
  914.         int record_len=0;
  915.        char record[RECORD_LENGTH+1];
  916.  
  917.        string_to_record(ptr,record,&record_len);
  918.        write_record (record_len,record);
  919.        write_integer(F_OK);
  920.       }
  921.    }
  922. }
  923.  
  924. /****  ADD1 end ****/
  925.  
  926.  
  927. void recieve_block ()
  928. {
  929.     long int source, block_size;
  930.     if (read_long_integer (&source))
  931.     if (read_long_integer (&block_size))
  932.     {
  933.         write_long_record(block_size, (char *) source);
  934.         write_integer(F_OK);
  935.     }
  936. }
  937.  
  938. send_block ()
  939. {
  940.     long int destination, block_size;
  941.     if (read_long_integer (&destination))
  942.     if (read_long_record (&block_size, (char *) destination))
  943.     {
  944.         write_long_integer(block_size);
  945.         write_integer(F_OK);
  946.     }
  947. }
  948.  
  949. /**** ADD2 begin ****/
  950.  
  951. call_interrupt ()
  952. {
  953.    /* NOT AVAILABLE ON AMIGA, JUST KEEP PROTOCOL */
  954.    unsigned char buffer[RECORD_LENGTH+1];
  955.    int interrupt,block_size, res=OPERATIONFAILED_ERR;
  956.  
  957.    if (read_integer(&interrupt))
  958.    if (read_record(&block_size,buffer))
  959.    {
  960.       write_integer(0);
  961.       write_record(0,"");
  962.       write_integer(res);
  963.    }
  964. }
  965.  
  966. read_regs()
  967. {
  968.    /* NOT AVAILABLE ON AMIGA */
  969.    write_record(0,"");
  970.    write_integer(OPERATIONFAILED_ERR);
  971. }
  972.  
  973. void port_read()
  974. {
  975.    /* NOT AVAILABLE ON AMIGA */
  976.    int address;
  977.  
  978.    if (read_integer(&address))
  979.    {
  980.       write_integer(0);
  981.       write_integer(OPERATIONFAILED_ERR);
  982.    }
  983. }
  984.  
  985.  
  986. void port_write()
  987. {
  988.    /* NOT AVAILABLE ON AMIGA */
  989.    int address, value;
  990.  
  991.    if(read_integer(&address))
  992.    if(read_integer(&value))
  993.    {
  994.       write_integer(OPERATIONFAILED_ERR);
  995.    }
  996. }
  997.  
  998. /**** ADD2 end ****/
  999.  
  1000. void add_to_tcom (str)
  1001. char *str;
  1002. {
  1003.     char c;
  1004.     while ((c = *str++) != '\0')
  1005.         tcom[tcominptr++] = c;
  1006.     tcom[tcominptr++] = ' ';
  1007. }
  1008.  
  1009. int tcomread (buffer, len)
  1010. char *buffer;
  1011. int len;
  1012. {
  1013.     int bytes_read = 0;
  1014.     while ( (tcomoutptr < tcominptr) && (bytes_read < len) )
  1015.     {
  1016.         *buffer++ = tcom[tcomoutptr++];
  1017.         bytes_read++;
  1018.     };
  1019.     return (bytes_read);
  1020. }
  1021.  
  1022. int read_number (str)
  1023. char *str;
  1024. {
  1025.     int result = 0;
  1026.     int base;
  1027.     int carry_on;
  1028.     int c;
  1029. if (*str == '#')
  1030. {
  1031.     base = 16; str++;
  1032. } else
  1033.     base = 10;
  1034.     carry_on = TRUE;
  1035.     while (carry_on)
  1036.     {
  1037.        c = *str++;
  1038.         if ((c >= '0') && (c <= '9'))
  1039.             result = (result * base) + c - '0';
  1040.         else
  1041.         {
  1042.             if (base == 16)
  1043.             {
  1044.                 if ((c >= 'a') && (c <= 'f'))
  1045.                     result = (result * base) + 10 + c - 'a';
  1046.                 else
  1047.                 {
  1048.                     if ((c >= 'A') && (c <= 'F'))
  1049.                         result = (result * base) + 10 + c - 'A';
  1050.                     else
  1051.                         carry_on = FALSE;
  1052.                 };
  1053.             } else
  1054.                 carry_on = FALSE;
  1055.         };
  1056.     };
  1057.     return (result);
  1058. }
  1059.  
  1060. int parse_command (argc, argv, boot_file_name)
  1061.   int argc;
  1062.   char *argv[], *boot_file_name;
  1063. /* Parse the command line typed in by the user. */
  1064. {
  1065.     char *ch;
  1066.     int i = 1;
  1067.     strcpy (boot_file_name, DEFAULT_BOOT_FILE);
  1068.     while (i < argc)
  1069.     {
  1070. ch = argv[i++];
  1071. switch (*ch++)
  1072. {
  1073. case '-':
  1074. case '/':
  1075. switch (*ch++)
  1076. {
  1077.     case ':' :
  1078. switch (*ch++)
  1079. {
  1080. case 'b':
  1081. if (i < argc)
  1082. {
  1083.     boot_file_exists = TRUE;
  1084.     strcpy (boot_file_name, argv[i++]);
  1085. }
  1086. else
  1087. {
  1088.     printf ("Missing boot file name parameter\n");
  1089.     return (FALSE);
  1090. };
  1091. break;
  1092. case 'l':
  1093. if (i < argc)
  1094. {
  1095.     link_base = read_number (argv[i++]);
  1096. } else
  1097. {
  1098.     printf ("Missing link address parameter\n");
  1099.     return (FALSE);
  1100. };
  1101. break;
  1102. case 'i':
  1103. printf (version);
  1104. printf ("Copyright INMOS Limited, 1987\n");
  1105. printf ("Amiga-Version modified by SANG-Computersysteme GmbH, 1988\n");
  1106. break;
  1107. case 'e':
  1108. test_error_flag = TRUE;
  1109. break;
  1110. /**** ADD3 begin ****/
  1111. case 'o':
  1112. if (i<argc)
  1113. {
  1114.    alien_option_flag = read_number(argv[i++]);
  1115. }
  1116. else
  1117. {
  1118.    printf("Missing alien option parameter\n");
  1119.    return(FALSE);
  1120. }
  1121. break;
  1122. /**** ADD3 end ****/
  1123. default:
  1124.     add_to_tcom ( argv[i-1] );
  1125.     break;
  1126. };
  1127. break;
  1128.     default :
  1129.         add_to_tcom ( argv[i-1] );
  1130.         break;
  1131. };
  1132. break;
  1133. default:
  1134.     add_to_tcom ( argv[i-1] );
  1135.     break;
  1136. };
  1137.     };
  1138.     return (TRUE);
  1139. }
  1140.  
  1141. void read_link ()
  1142. /* Read a message coming down the link. */
  1143. {
  1144.     if (read_integer (&command))
  1145.     {
  1146. #ifdef DEBUG
  1147.         printf("Transputer sending command %d \n",command);
  1148. #endif
  1149.         switch (command)
  1150. {
  1151. case TERMINATE_CMD:
  1152.     filer_close ();
  1153.     write_integer (F_OK);
  1154.     terminate_server (T_TERMINATED);
  1155.     break;
  1156. case ALIENTERMINATE_CMD:
  1157.     write_integer (F_OK);
  1158.     break;
  1159. case OPENFILE_CMD:
  1160.     open_file (PERMANENT); break;
  1161. case OPENTEMP_CMD:
  1162.     open_temp (); break;
  1163. case OPENINPUTSTREAM_CMD:
  1164.     open_stream (S_INPUT); break;
  1165. case OPENOUTPUTSTREAM_CMD:
  1166.     open_stream (S_OUTPUT); break;
  1167. case STREAMACCESS_CMD:
  1168.     stream_access (); break;
  1169. case STREAMSTATUS_CMD:
  1170.     stream_status (); break;
  1171. case STREAMFILE_CMD:
  1172.     stream_file (); break;
  1173. case STREAMLENGTH_CMD:
  1174.     stream_length (); break;
  1175. case STREAMCONNECT_CMD:
  1176.     stream_connect (); break;
  1177. case CLOSESTREAM_CMD:
  1178.     close_stream (); break;
  1179. case READBLOCK_CMD:
  1180.     read_block (); break;
  1181. case WRITEBLOCK_CMD:
  1182.     write_block (); break;
  1183. case SEEK_CMD:
  1184.     stream_seek (); break;
  1185. case SETRESULT_CMD:
  1186.     set_result (); break;
  1187. case RUNCOMMAND_CMD:
  1188.     run_command (); break;
  1189. case RENAMEFILE_CMD:
  1190.     rename_file (); break;
  1191. case READTIME_CMD:
  1192.     read_time (); break;
  1193. case RUNTIMEDATA_CMD:
  1194.     run_time_data(); break;
  1195. case READENVIRONMENT_CMD:
  1196.     read_environment(); break;
  1197. case READKEY_CMD:
  1198.     read_key (); break;
  1199. case RECIEVEBLOCK_CMD :
  1200.     recieve_block (); break;
  1201. case SENDBLOCK_CMD:
  1202.     send_block (); break;
  1203. /**** ADD4 begin ****/
  1204. case CALLINTERRUPT_CMD:
  1205.     call_interrupt(); break;
  1206. case READREGS_CMD:
  1207.     read_regs(); break;
  1208. case PORTREAD_CMD:
  1209.     port_read(); break;
  1210. case PORTWRITE_CMD:
  1211.     port_write(); break;
  1212. /**** ADD4 end ****/
  1213. default:
  1214.     terminate_server (T_ILLEGAL_COMMAND);
  1215. }
  1216.     };
  1217. }
  1218.  
  1219. void root_error ()
  1220. /* Process an error in the transputer system. */
  1221. {
  1222.     terminate_server (T_TRANSPUTER_ERR);
  1223. }
  1224.  
  1225. void terminate_message (t_code)
  1226. int t_code;
  1227. /* Report the server's reason for termination. */
  1228. {
  1229.     switch (t_code)
  1230.     {
  1231.     case T_TERMINATED:        break;
  1232.     case T_USR_STOP:
  1233.     case T_USR_BRK:
  1234.           fprintf (stderr, "Server aborted by user\n"); break;
  1235.     case T_TRANSPUTER_ERR:
  1236.           fprintf (stderr, 
  1237.                 "Server terminated: error in transputer system\n");
  1238.           break;
  1239.     case T_BAD_BOOT:
  1240.           fprintf (stderr, 
  1241.                 "Server terminated: cannot boot root transputer\n");
  1242.           break;
  1243.     case T_ILLEGAL_COMMAND:
  1244.         fprintf (stderr,
  1245.               "Server terminated: illegal filer command received\n");
  1246.           break;
  1247.     case T_BAD_COMMAND_LINE:
  1248.           fprintf (stderr, "Server terminated: bad command line\n");
  1249.           break;
  1250.     case T_BAD_RECORD:
  1251.           fprintf (stderr,
  1252.                   "Server terminated: bad protocol when expecting record\n");
  1253.           break;
  1254.     case T_BAD_INT32:
  1255.           fprintf (stderr,
  1256.                   "Server terminated: bad protocol when expecting INT32\n");
  1257.           break;
  1258.     }
  1259. }
  1260.  
  1261. int root_init( boot_file_name, analyse_flag )
  1262. char boot_file_name[];
  1263. int analyse_flag;
  1264. /* Initialise the root transputer board by resetting it and sending the boot
  1265.    file to it. */
  1266. {
  1267.     init_root();
  1268.     if (boot_file_exists)
  1269.     {
  1270.         printf ( "Booting root transputer ...\n" ); 
  1271.         if (analyse_flag)
  1272.             reset_analyse_root();
  1273.         else
  1274.             reset_root();
  1275.         return (boot_root ( boot_file_name ));
  1276.     }
  1277.     else
  1278.         return(F_OK);
  1279. }
  1280.  
  1281. void filer_init ()
  1282. {
  1283.     int i;
  1284.     for (i = 0; i < N_STREAMS; i++)
  1285.         filers[i].inuse = FALSE;
  1286. }
  1287.  
  1288. /**** REMARK: DIFFERENT ****/
  1289.  
  1290. int usr_brk_handler (sig)
  1291. int sig;
  1292. /* Process a user break ( control-break on the keyboard ). */
  1293. {
  1294.     terminate_server(T_USR_BRK);
  1295. }
  1296.  
  1297. int server_main()
  1298. {
  1299.    while (running)
  1300.    {
  1301.           if(link_in_test())  read_link();
  1302.      Chk_Abort();
  1303.    }
  1304. }
  1305.  
  1306. int main (argc, argv, envp)
  1307. int argc;
  1308. char *argv[], *envp[];
  1309. {
  1310.     int analyse_flag = FALSE,   /* Boot transputer in analyse mode flag */
  1311.         init_flag;              /* Boot transputer flag */
  1312.     char boot_file_name[FILE_NAME_LENGTH];
  1313.     if (!parse_command(argc, argv, boot_file_name))  /* Parse command line */
  1314.     {
  1315.         terminate_code = T_BAD_COMMAND_LINE;
  1316.         init_flag = FALSE;
  1317.     }
  1318.     else
  1319.         init_flag = TRUE;
  1320.     while (init_flag)
  1321.     {
  1322. running = TRUE;
  1323. init_flag = FALSE;
  1324. terminate_code = 0;
  1325. filer_init();
  1326. if (root_init (boot_file_name, analyse_flag) == F_OK)
  1327. {
  1328. /*    signal (SIGINT, usr_brk_handler); */
  1329.     server_main ();
  1330. switch (terminate_code)
  1331. {
  1332.     case T_TRANSPUTER_ERR:
  1333.         fprintf (stderr, "Error in transputer system\n");
  1334.     case T_USR_BRK:
  1335.     {
  1336.         int key;
  1337.         filer_close();
  1338.         analyse_flag = TRUE;
  1339.         break;
  1340.     }
  1341.     default: break;
  1342. };
  1343. }
  1344. else
  1345.     terminate_code = T_BAD_BOOT;
  1346.     };
  1347.     terminate_message (terminate_code);
  1348.     exit(transputer_result);
  1349. }
  1350.